/**
 * This project create for studying propose at BUPT University. You can change or reuse this project anywhere
 */

package edu.bupt.ooad.library;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Hamed Abdollahpour
 */
public class Library {

    // private final static Logger logger =
    // LoggerFactory.getLogger(Library.class);

    private List<Patron> patrons = new ArrayList<Patron>();

    private List<BookDescription> descriptions = new ArrayList<BookDescription>();

    private PeristanceTools peristanceTools = new PeristanceTools();

    public List<Book> addBook(BookDescription description, int quantity) {
        if (description == null) {
            throw new IllegalArgumentException("null description");
        }

        if (!descriptions.contains(description)) {
            descriptions.add(description);
        }

        List<Book> results = new ArrayList<Book>();

        for (BookDescription desc : descriptions) {
            for (int i = 0; i < quantity; i++) {
                int id = peristanceTools.nextUniqueId();
                Book book = desc.createBook(id);
                desc.addBook(book);

                results.add(book);
            }
        }

        return results;
    }

    public void removeBook(Book book) {
        BookDescription description = book.getDescription();

        returnBook(book);
        description.removeBook(book);
    }

    public void borrowBook(Patron patron, Book book) {
        patron.barrowBook(book);
    }

    public void borrowBook(int patronId, int bookId) {
        Patron patron = searchPatron(patronId);
        if (patron == null) {
            throw new IllegalArgumentException("Patron not found!");
        }

        Book book = searchBook(bookId);
        if (book == null) {
            throw new IllegalArgumentException("Book not found!");
        }

        borrowBook(patron, book);
    }

    public void returnBook(int bookId) {
        Book book = searchBook(bookId);
        if (book == null) {
            throw new IllegalArgumentException("Book not found!");
        }

        returnBook(book);
    }

    public void returnBook(Book book) {
        for (Patron patron : patrons) {
            patron.returnBook(book);
        }
    }

    public List<BookDescription> searchDescriptions(String title, String author, String category,
            int isbn) {
        BookDescription description = new BookDescription();
        description.setTitle(title);
        description.setAuthor(author);
        description.setCategory(category);
        description.setIsbn(isbn);

        List<BookDescription> results = new ArrayList<BookDescription>();

        for (BookDescription desc : descriptions) {
            if (isMatchDesc(description, desc)) {
                results.add(desc);
            }
        }

        return results;
    }

    public Book searchBook(int bookId) {
        for (BookDescription description : descriptions) {
            Book book = description.getBook(bookId);
            if (book != null) {
                return book;
            }
        }
        return null;
    }

    public Patron searchPatron(int id) {
        for (Patron patron : patrons) {
            if (patron.getId() == id) {
                return patron;
            }
        }
        return null;
    }

    public BookDescription createDescriptions(String title, String author, String category, int isbn) {
        BookDescription description = new BookDescription();
        description.setTitle(title);
        description.setAuthor(author);
        description.setCategory(category);
        description.setIsbn(isbn);

        if (!descriptions.contains(description)) {
            descriptions.add(description);
        }

        return description;
    }

    private boolean isMatchDesc(BookDescription desc1, BookDescription desc2) {
        // match for title
        String title1 = desc1.getTitle();
        String title2 = desc2.getTitle();
        if (!isEqualField(title1, title2)) {
            return false;
        }

        // match for category
        String category1 = desc1.getCategory();
        String category2 = desc2.getCategory();
        if (!isEqualField(category1, category2)) {
            return false;
        }

        // match for description
        String author1 = desc1.getAuthor();
        String author2 = desc2.getAuthor();
        if (!isEqualField(author1, author2)) {
            return false;
        }

        // match for ISBN
        int isbn1 = desc1.getIsbn();
        int isbn2 = desc2.getIsbn();
        if (isbn1 != 0 && isbn1 != isbn2) {
            return false;
        }

        return true;
    }

    private boolean isEqualField(String s1, String s2) {
        if (s1 == null || s1.length() == 0) {
            return true;
        }
        return s1.equalsIgnoreCase(s2);
    }

    public List<Patron> getPatrons() {
        return patrons;
    }

    public boolean createStudent(String firstname, String lastname, int studentId) {
        Student student = new Student();
        student.setFirstname(firstname);
        student.setLastname(lastname);
        student.setStudentId(studentId);
        student.setId(peristanceTools.nextUniqueId());

        patrons.add(student);

        return true;
    }

    public boolean createTeacher(String firstname, String lastname, String department) {
        Teacher teacher = new Teacher();
        teacher.setFirstname(firstname);
        teacher.setLastname(lastname);
        teacher.setDepartment(department);
        teacher.setId(peristanceTools.nextUniqueId());

        patrons.add(teacher);

        return true;
    }
}
